--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
tests/backend/test_performance_hotpaths.py 9d7ae2017b7a4f378eaebadf3a24bf066e5d3eb9 (9d7ae201) Text, 22.12 KB
T8b949e"""Performance regression tests for the critical hot paths.
Focus areas (user priority):
- NomadNet browser: load announces, search announces, favourites
- Messages: load conversations, search messages, load conversation messages,
upsert messages (drafts)
Metrics collected:
- ops/sec throughput
- p50 / p95 / p99 latency
- Concurrent writer contention
- LIKE-search scaling
All tests have hard assertions so regressions fail CI.
"""
Tff7b72import T7ee787os
Tff7b72import T7ee787secrets
Tff7b72import T7ee787shutil
Tff7b72import T7ee787statistics
Tff7b72import T7ee787tempfile
Tff7b72import T7ee787threading
Tff7b72import T7ee787time
Tff7b72import T7ee787unittest
Tff7b72from T7ee787unittestT7ee787.T7ee787mock Tff7b72import Te6edf3MagicMock
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787announce_manager Tff7b72import Te6edf3AnnounceManager
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787database Tff7b72import Te6edf3Database
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787message_handler Tff7b72import Te6edf3MessageHandler
T8b949e# ---------------------------------------------------------------------------
T8b949e# Helpers
T8b949e# ---------------------------------------------------------------------------
Tff7b72def Td2a8ffpercentileTb4b4b4(Te6edf3dataTb4b4b4, Te6edf3pctTb4b4b4)Tb4b4b4:
T8b949e"""Return the pct-th percentile of sorted data."""
Tff7b72if Tff7b72not Te6edf3dataTb4b4b4:
Tff7b72return T79c0ff0
Te6edf3s Tff7b72= Tffa657sortedTb4b4b4(Te6edf3dataTb4b4b4)
Te6edf3k Tff7b72= Tb4b4b4(Tffa657lenTb4b4b4(Te6edf3sTb4b4b4) Tff7b72- T79c0ff1Tb4b4b4) Tff7b72* Tb4b4b4(Te6edf3pct Tff7b72/ T79c0ff100Tb4b4b4)
Te6edf3f Tff7b72= Tffa657intTb4b4b4(Te6edf3kTb4b4b4)
Te6edf3c Tff7b72= Te6edf3f Tff7b72+ T79c0ff1
Tff7b72if Te6edf3c Tff7b72>Tff7b72= Tffa657lenTb4b4b4(Te6edf3sTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3sTb4b4b4[Te6edf3fTb4b4b4]
Tff7b72return Te6edf3sTb4b4b4[Te6edf3fTb4b4b4] Tff7b72+ Tb4b4b4(Te6edf3k Tff7b72- Te6edf3fTb4b4b4) Tff7b72* Tb4b4b4(Te6edf3sTb4b4b4[Te6edf3cTb4b4b4] Tff7b72- Te6edf3sTb4b4b4[Te6edf3fTb4b4b4]Tb4b4b4)
Tff7b72def Td2a8fftimed_callTb4b4b4(Te6edf3fnTb4b4b4, Tff7b72*Te6edf3argsTb4b4b4, Tff7b72*Tff7b72*Te6edf3kwargsTb4b4b4)Tb4b4b4:
T8b949e"""Call fn and return (result, duration_ms)."""
Te6edf3t0 Tff7b72= Te6edf3timeTff7b72.Td2a8ffperf_counterTb4b4b4(Tb4b4b4)
Te6edf3result Tff7b72= Te6edf3fnTb4b4b4(Tff7b72*Te6edf3argsTb4b4b4, Tff7b72*Tff7b72*Te6edf3kwargsTb4b4b4)
Tff7b72return Te6edf3resultTb4b4b4, Tb4b4b4(Te6edf3timeTff7b72.Td2a8ffperf_counterTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3t0Tb4b4b4) Tff7b72* T79c0ff1000
Tff7b72def Td2a8fflatency_reportTb4b4b4(Te6edf3nameTb4b4b4, Te6edf3durations_msTb4b4b4)Tb4b4b4:
T8b949e"""Print and return latency stats."""
Te6edf3p50 Tff7b72= Te6edf3percentileTb4b4b4(Te6edf3durations_msTb4b4b4, T79c0ff50Tb4b4b4)
Te6edf3p95 Tff7b72= Te6edf3percentileTb4b4b4(Te6edf3durations_msTb4b4b4, T79c0ff95Tb4b4b4)
Te6edf3p99 Tff7b72= Te6edf3percentileTb4b4b4(Te6edf3durations_msTb4b4b4, T79c0ff99Tb4b4b4)
Te6edf3avg Tff7b72= Te6edf3statisticsTff7b72.Td2a8ffmeanTb4b4b4(Te6edf3durations_msTb4b4b4)
Te6edf3ops Tff7b72= T79c0ff1000 Tff7b72/ Te6edf3avg Tff7b72if Te6edf3avg Tff7b72> T79c0ff0 Tff7b72else Tffa657floatTb4b4b4(Ta5d6ff"Ta5d6ffinfTa5d6ff"Tb4b4b4)
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ff Tffd700{Te6edf3nameTffd700}Ta5d6ff: avg=Tffd700{Te6edf3avgTffd700:Ta5d6ff.2fTffd700}Ta5d6ffms p50=Tffd700{Te6edf3p50Tffd700:Ta5d6ff.2fTffd700}Ta5d6ffms p95=Tffd700{Te6edf3p95Tffd700:Ta5d6ff.2fTffd700}Ta5d6ffms Ta5d6ff"
Ta5d6fffTa5d6ff"Ta5d6ffp99=Tffd700{Te6edf3p99Tffd700:Ta5d6ff.2fTffd700}Ta5d6ffms ops/s=Tffd700{Te6edf3opsTffd700:Ta5d6ff.0fTffd700}Ta5d6ff"
Tb4b4b4)
Tff7b72return Tb4b4b4{Ta5d6ff"Ta5d6ffavgTa5d6ff"Tb4b4b4: Te6edf3avgTb4b4b4, Ta5d6ff"Ta5d6ffp50Ta5d6ff"Tb4b4b4: Te6edf3p50Tb4b4b4, Ta5d6ff"Ta5d6ffp95Ta5d6ff"Tb4b4b4: Te6edf3p95Tb4b4b4, Ta5d6ff"Ta5d6ffp99Ta5d6ff"Tb4b4b4: Te6edf3p99Tb4b4b4, Ta5d6ff"Ta5d6ffopsTa5d6ff"Tb4b4b4: Te6edf3opsTb4b4b4}
Tff7b72def Td2a8ffmake_messageTb4b4b4(Te6edf3peer_hashTb4b4b4, Te6edf3iTb4b4b4, Te6edf3content_sizeTff7b72=T79c0ff100Tb4b4b4)Tb4b4b4:
Tff7b72return Tb4b4b4{
Ta5d6ff"Ta5d6ffhashTa5d6ff"Tb4b4b4: Te6edf3secretsTff7b72.Td2a8fftoken_hexTb4b4b4(T79c0ff16Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffsource_hashTa5d6ff"Tb4b4b4: Te6edf3peer_hashTb4b4b4,
Ta5d6ff"Ta5d6ffdestination_hashTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6fflocal_hash_0Ta5d6ff" Tff7b72* T79c0ff2Tb4b4b4,
Ta5d6ff"Ta5d6ffpeer_hashTa5d6ff"Tb4b4b4: Te6edf3peer_hashTb4b4b4,
Ta5d6ff"Ta5d6ffstateTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffdeliveredTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffprogressTa5d6ff"Tb4b4b4: T79c0ff1.0Tb4b4b4,
Ta5d6ff"Ta5d6ffis_incomingTa5d6ff"Tb4b4b4: Te6edf3i Tff7b72% T79c0ff2Tb4b4b4,
Ta5d6ff"Ta5d6ffmethodTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffdirectTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffdelivery_attemptsTa5d6ff"Tb4b4b4: T79c0ff1Tb4b4b4,
Ta5d6ff"Ta5d6ffnext_delivery_attempt_atTa5d6ff"Tb4b4b4: Tff7b72NoneTb4b4b4,
Ta5d6ff"Ta5d6fftitleTa5d6ff"Tb4b4b4: Ta5d6fffTa5d6ff"Ta5d6ffMessage title Tffd700{Te6edf3iTffd700}Ta5d6ff Ta5d6ff" Tff7b72+ Te6edf3secretsTff7b72.Td2a8fftoken_hexTb4b4b4(T79c0ff8Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffcontentTa5d6ff"Tb4b4b4: Ta5d6fffTa5d6ff"Ta5d6ffContent body Tffd700{Te6edf3iTffd700}Ta5d6ff Ta5d6ff" Tff7b72+ Ta5d6ff"Ta5d6ffxTa5d6ff" Tff7b72* Te6edf3content_sizeTb4b4b4,
Ta5d6ff"Ta5d6fffieldsTa5d6ff"Tb4b4b4: Ta5d6ff"Tffd700{}Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fftimestampTa5d6ff"Tb4b4b4: Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3iTb4b4b4,
Ta5d6ff"Ta5d6ffrssiTa5d6ff"Tb4b4b4: Tff7b72-T79c0ff50Tb4b4b4,
Ta5d6ff"Ta5d6ffsnrTa5d6ff"Tb4b4b4: T79c0ff5.0Tb4b4b4,
Ta5d6ff"Ta5d6ffqualityTa5d6ff"Tb4b4b4: T79c0ff3Tb4b4b4,
Ta5d6ff"Ta5d6ffis_spamTa5d6ff"Tb4b4b4: T79c0ff0Tb4b4b4,
Ta5d6ff"Ta5d6ffreply_to_hashTa5d6ff"Tb4b4b4: Tff7b72NoneTb4b4b4,
Tb4b4b4}
Tff7b72def Td2a8ffmake_announceTb4b4b4(Te6edf3iTb4b4b4)Tb4b4b4:
Tff7b72return Tb4b4b4{
Ta5d6ff"Ta5d6ffdestination_hashTa5d6ff"Tb4b4b4: Te6edf3secretsTff7b72.Td2a8fftoken_hexTb4b4b4(T79c0ff16Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffaspectTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6fflxmf.deliveryTa5d6ff" Tff7b72if Te6edf3i Tff7b72% T79c0ff3 Tff7b72!= T79c0ff0 Tff7b72else Ta5d6ff"Ta5d6fflxst.telephonyTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffidentity_hashTa5d6ff"Tb4b4b4: Te6edf3secretsTff7b72.Td2a8fftoken_hexTb4b4b4(T79c0ff16Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffidentity_public_keyTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffpubkey_Ta5d6ff" Tff7b72+ Te6edf3secretsTff7b72.Td2a8fftoken_hexTb4b4b4(T79c0ff8Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffapp_dataTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffappdata_Ta5d6ff" Tff7b72+ Te6edf3secretsTff7b72.Td2a8fftoken_hexTb4b4b4(T79c0ff16Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffrssiTa5d6ff"Tb4b4b4: Tff7b72-T79c0ff50 Tff7b72+ Tb4b4b4(Te6edf3i Tff7b72% T79c0ff30Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffsnrTa5d6ff"Tb4b4b4: T79c0ff5.0Tb4b4b4,
Ta5d6ff"Ta5d6ffqualityTa5d6ff"Tb4b4b4: Te6edf3i Tff7b72% T79c0ff10Tb4b4b4,
Tb4b4b4}
T8b949e# ---------------------------------------------------------------------------
T8b949e# Test class
T8b949e# ---------------------------------------------------------------------------
Tff7b72class T56d364TestPerformanceHotPathsTb4b4b4(Te6edf3unittestTff7b72.Td2a8ffTestCaseTb4b4b4)Tb4b4b4:
Te6edf3NUM_MESSAGES Tff7b72= T79c0ff10_000
Te6edf3NUM_PEERS Tff7b72= T79c0ff200
Te6edf3NUM_ANNOUNCES Tff7b72= T79c0ff5_000
Te6edf3NUM_FAVOURITES Tff7b72= T79c0ff100
Te6edf3NUM_CONTACTS Tff7b72= T79c0ff50
Tf0883e@classmethod
Tff7b72def Td2a8ffsetUpClassTb4b4b4(Tff7b72clsTb4b4b4)Tb4b4b4:
Tff7b72clsTff7b72.Td2a8fftest_dir Tff7b72= Te6edf3tempfileTff7b72.Td2a8ffmkdtempTb4b4b4(Tb4b4b4)
Tff7b72clsTff7b72.Td2a8ffdb_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Tff7b72clsTff7b72.Td2a8fftest_dirTb4b4b4, Ta5d6ff"Ta5d6ffperf_hotpaths.dbTa5d6ff"Tb4b4b4)
Tff7b72clsTff7b72.Td2a8ffdb Tff7b72= Te6edf3DatabaseTb4b4b4(Tff7b72clsTff7b72.Td2a8ffdb_pathTb4b4b4)
Tff7b72clsTff7b72.Td2a8ffdbTff7b72.Td2a8ffinitializeTb4b4b4(Tb4b4b4)
Tff7b72clsTff7b72.Td2a8ffhandler Tff7b72= Te6edf3MessageHandlerTb4b4b4(Tff7b72clsTff7b72.Td2a8ffdbTb4b4b4)
Tff7b72clsTff7b72.Td2a8ffannounce_mgr Tff7b72= Te6edf3AnnounceManagerTb4b4b4(Tff7b72clsTff7b72.Td2a8ffdbTb4b4b4)
Tff7b72clsTff7b72.Td2a8ff_seed_dataTb4b4b4(Tb4b4b4)
Tf0883e@classmethod
Tff7b72def Td2a8fftearDownClassTb4b4b4(Tff7b72clsTb4b4b4)Tb4b4b4:
Tff7b72clsTff7b72.Td2a8ffdbTff7b72.Td2a8ffclose_allTb4b4b4(Tb4b4b4)
Te6edf3shutilTff7b72.Td2a8ffrmtreeTb4b4b4(Tff7b72clsTff7b72.Td2a8fftest_dirTb4b4b4, Te6edf3ignore_errorsTff7b72=Tff7b72TrueTb4b4b4)
Tf0883e@classmethod
Tff7b72def Td2a8ff_seed_dataTb4b4b4(Tff7b72clsTb4b4b4)Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Tffea00\nTa5d6ff--- Seeding test data ---Ta5d6ff"Tb4b4b4)
T8b949e# Peers
Tff7b72clsTff7b72.Td2a8ffpeer_hashes Tff7b72= Tb4b4b4[Te6edf3secretsTff7b72.Td2a8fftoken_hexTb4b4b4(T79c0ff16Tb4b4b4) Tff7b72for Te6edf3_ Tff7b72in Tffa657rangeTb4b4b4(Tff7b72clsTff7b72.Td2a8ffNUM_PEERSTb4b4b4)Tb4b4b4]
Tff7b72clsTff7b72.Td2a8ffheavy_peer Tff7b72= Tff7b72clsTff7b72.Td2a8ffpeer_hashesTb4b4b4[T79c0ff0Tb4b4b4]
T8b949e# Messages: distribute across peers, heavy_peer gets 2000
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ff Seeding Tffd700{Tff7b72clsTff7b72.Td2a8ffNUM_MESSAGESTffd700}Ta5d6ff messages across Tffd700{Tff7b72clsTff7b72.Td2a8ffNUM_PEERSTffd700}Ta5d6ff peers...Ta5d6ff"Tb4b4b4)
Te6edf3t0 Tff7b72= Te6edf3timeTff7b72.Td2a8ffperf_counterTb4b4b4(Tb4b4b4)
Tff7b72with Tff7b72clsTff7b72.Td2a8ffdbTff7b72.Td2a8ffproviderTb4b4b4:
Tff7b72for Te6edf3i Tff7b72in Tffa657rangeTb4b4b4(Tff7b72clsTff7b72.Td2a8ffNUM_MESSAGESTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3i Tff7b72< T79c0ff2000Tb4b4b4:
Te6edf3peer Tff7b72= Tff7b72clsTff7b72.Td2a8ffheavy_peer
Tff7b72elseTb4b4b4:
Te6edf3peer Tff7b72= Tff7b72clsTff7b72.Td2a8ffpeer_hashesTb4b4b4[Te6edf3i Tff7b72% Tff7b72clsTff7b72.Td2a8ffNUM_PEERSTb4b4b4]
Tff7b72clsTff7b72.Td2a8ffdbTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffupsert_lxmf_messageTb4b4b4(Te6edf3make_messageTb4b4b4(Te6edf3peerTb4b4b4, Te6edf3iTb4b4b4)Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ff Done in Tffd700{Tb4b4b4(Te6edf3timeTff7b72.Td2a8ffperf_counterTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3t0Tb4b4b4) Tff7b72* T79c0ff1000Tffd700:Ta5d6ff.0fTffd700}Ta5d6ffmsTa5d6ff"Tb4b4b4)
T8b949e# Announces
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ff Seeding Tffd700{Tff7b72clsTff7b72.Td2a8ffNUM_ANNOUNCESTffd700}Ta5d6ff announces...Ta5d6ff"Tb4b4b4)
Tff7b72clsTff7b72.Td2a8ffannounce_hashes Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3t0 Tff7b72= Te6edf3timeTff7b72.Td2a8ffperf_counterTb4b4b4(Tb4b4b4)
Tff7b72with Tff7b72clsTff7b72.Td2a8ffdbTff7b72.Td2a8ffproviderTb4b4b4:
Tff7b72for Te6edf3i Tff7b72in Tffa657rangeTb4b4b4(Tff7b72clsTff7b72.Td2a8ffNUM_ANNOUNCESTb4b4b4)Tb4b4b4:
Te6edf3data Tff7b72= Te6edf3make_announceTb4b4b4(Te6edf3iTb4b4b4)
Tff7b72clsTff7b72.Td2a8ffannounce_hashesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3dataTb4b4b4[Ta5d6ff"Ta5d6ffdestination_hashTa5d6ff"Tb4b4b4]Tb4b4b4)
Tff7b72clsTff7b72.Td2a8ffdbTff7b72.Td2a8ffannouncesTff7b72.Td2a8ffupsert_announceTb4b4b4(Te6edf3dataTb4b4b4)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ff Done in Tffd700{Tb4b4b4(Te6edf3timeTff7b72.Td2a8ffperf_counterTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3t0Tb4b4b4) Tff7b72* T79c0ff1000Tffd700:Ta5d6ff.0fTffd700}Ta5d6ffmsTa5d6ff"Tb4b4b4)
T8b949e# Favourites
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ff Seeding Tffd700{Tff7b72clsTff7b72.Td2a8ffNUM_FAVOURITESTffd700}Ta5d6ff favourites...Ta5d6ff"Tb4b4b4)
Tff7b72with Tff7b72clsTff7b72.Td2a8ffdbTff7b72.Td2a8ffproviderTb4b4b4:
Tff7b72for Te6edf3i Tff7b72in Tffa657rangeTb4b4b4(Tff7b72clsTff7b72.Td2a8ffNUM_FAVOURITESTb4b4b4)Tb4b4b4:
Tff7b72clsTff7b72.Td2a8ffdbTff7b72.Td2a8ffannouncesTff7b72.Td2a8ffupsert_favouriteTb4b4b4(
Tff7b72clsTff7b72.Td2a8ffannounce_hashesTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4,
Ta5d6fffTa5d6ff"Ta5d6ffFav Node Tffd700{Te6edf3iTffd700}Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fflxmf.deliveryTa5d6ff"Tb4b4b4,
Tb4b4b4)
T8b949e# Contacts (for JOIN benchmarks)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ff Seeding Tffd700{Tff7b72clsTff7b72.Td2a8ffNUM_CONTACTSTffd700}Ta5d6ff contacts...Ta5d6ff"Tb4b4b4)
Tff7b72with Tff7b72clsTff7b72.Td2a8ffdbTff7b72.Td2a8ffproviderTb4b4b4:
Tff7b72for Te6edf3i Tff7b72in Tffa657rangeTb4b4b4(Tff7b72clsTff7b72.Td2a8ffNUM_CONTACTSTb4b4b4)Tb4b4b4:
Tff7b72clsTff7b72.Td2a8ffdbTff7b72.Td2a8ffcontactsTff7b72.Td2a8ffadd_contactTb4b4b4(
Te6edf3nameTff7b72=Ta5d6fffTa5d6ff"Ta5d6ffContact Tffd700{Te6edf3iTffd700}Ta5d6ff"Tb4b4b4,
Te6edf3remote_identity_hashTff7b72=Tff7b72clsTff7b72.Td2a8ffpeer_hashesTb4b4b4[Te6edf3i Tff7b72% Tff7b72clsTff7b72.Td2a8ffNUM_PEERSTb4b4b4]Tb4b4b4,
Te6edf3lxmf_addressTff7b72=Tff7b72clsTff7b72.Td2a8ffpeer_hashesTb4b4b4[Tb4b4b4(Te6edf3i Tff7b72+ T79c0ff1Tb4b4b4) Tff7b72% Tff7b72clsTff7b72.Td2a8ffNUM_PEERSTb4b4b4]Tb4b4b4,
Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ff--- Seeding complete ---Tffea00\nTa5d6ff"Tb4b4b4)
T8b949e# ===================================================================
T8b949e# ANNOUNCES — load, search, count
T8b949e# ===================================================================
Tff7b72def Td2a8fftest_announce_load_filtered_latencyTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Load announces filtered by aspect with pagination — the NomadNet browser default view."""
Tffa657printTb4b4b4(Ta5d6ff"Tffea00\nTa5d6ff[Announce] Filtered load (aspect + pagination):Ta5d6ff"Tb4b4b4)
Te6edf3durations Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3offsets Tff7b72= Tb4b4b4[T79c0ff0Tb4b4b4, T79c0ff100Tb4b4b4, T79c0ff500Tb4b4b4, T79c0ff1000Tb4b4b4, T79c0ff2000Tb4b4b4]
Tff7b72for Te6edf3offset Tff7b72in Te6edf3offsetsTb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3ms Tff7b72= Te6edf3timed_callTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffannounce_mgrTff7b72.Td2a8ffget_filtered_announcesTb4b4b4,
Te6edf3aspectTff7b72=Ta5d6ff"Ta5d6fflxmf.deliveryTa5d6ff"Tb4b4b4,
Te6edf3limitTff7b72=T79c0ff50Tb4b4b4,
Te6edf3offsetTff7b72=Te6edf3offsetTb4b4b4,
Tb4b4b4)
Te6edf3durationsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msTb4b4b4)
Te6edf3stats Tff7b72= Te6edf3latency_reportTb4b4b4(Ta5d6ff"Ta5d6fffiltered_loadTa5d6ff"Tb4b4b4, Te6edf3durationsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertLessTb4b4b4(Te6edf3statsTb4b4b4[Ta5d6ff"Ta5d6ffp99Ta5d6ff"Tb4b4b4]Tb4b4b4, T79c0ff100Tb4b4b4, Ta5d6ff"Ta5d6ffAnnounce filtered load p99 > 100msTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8fftest_announce_search_latencyTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Search announces by destination/identity hash substring."""
Tffa657printTb4b4b4(Ta5d6ff"Tffea00\nTa5d6ff[Announce] LIKE search:Ta5d6ff"Tb4b4b4)
Te6edf3search_terms Tff7b72= Tb4b4b4[
Te6edf3secretsTff7b72.Td2a8fftoken_hexTb4b4b4(T79c0ff4Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffabcTa5d6ff"Tb4b4b4,
Tff7b72selfTff7b72.Td2a8ffannounce_hashesTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4[Tb4b4b4:T79c0ff8Tb4b4b4]Tb4b4b4,
Tff7b72selfTff7b72.Td2a8ffannounce_hashesTb4b4b4[T79c0ff2500Tb4b4b4]Tb4b4b4[Tb4b4b4:T79c0ff10Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6ffnonexistent_term_xyzTa5d6ff"Tb4b4b4,
Tb4b4b4]
Te6edf3durations Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3term Tff7b72in Te6edf3search_termsTb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3ms Tff7b72= Te6edf3timed_callTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffannounce_mgrTff7b72.Td2a8ffget_filtered_announcesTb4b4b4,
Te6edf3aspectTff7b72=Ta5d6ff"Ta5d6fflxmf.deliveryTa5d6ff"Tb4b4b4,
Te6edf3queryTff7b72=Te6edf3termTb4b4b4,
Te6edf3limitTff7b72=T79c0ff50Tb4b4b4,
Te6edf3offsetTff7b72=T79c0ff0Tb4b4b4,
Tb4b4b4)
Te6edf3durationsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msTb4b4b4)
Te6edf3stats Tff7b72= Te6edf3latency_reportTb4b4b4(Ta5d6ff"Ta5d6ffsearchTa5d6ff"Tb4b4b4, Te6edf3durationsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertLessTb4b4b4(Te6edf3statsTb4b4b4[Ta5d6ff"Ta5d6ffp95Ta5d6ff"Tb4b4b4]Tb4b4b4, T79c0ff150Tb4b4b4, Ta5d6ff"Ta5d6ffAnnounce search p95 > 150msTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8fftest_announce_search_with_blockedTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Search with a block-list — simulates real NomadNet browser filtering."""
Tffa657printTb4b4b4(Ta5d6ff"Tffea00\nTa5d6ff[Announce] Search with blocked list:Ta5d6ff"Tb4b4b4)
Te6edf3blocked Tff7b72= Tb4b4b4[Te6edf3secretsTff7b72.Td2a8fftoken_hexTb4b4b4(T79c0ff16Tb4b4b4) Tff7b72for Te6edf3_ Tff7b72in Tffa657rangeTb4b4b4(T79c0ff50Tb4b4b4)Tb4b4b4]
Te6edf3durations Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3_ Tff7b72in Tffa657rangeTb4b4b4(T79c0ff20Tb4b4b4)Tb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3ms Tff7b72= Te6edf3timed_callTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffannounce_mgrTff7b72.Td2a8ffget_filtered_announcesTb4b4b4,
Te6edf3aspectTff7b72=Ta5d6ff"Ta5d6fflxmf.deliveryTa5d6ff"Tb4b4b4,
Te6edf3queryTff7b72=Ta5d6ff"Ta5d6ffabcTa5d6ff"Tb4b4b4,
Te6edf3blocked_identity_hashesTff7b72=Te6edf3blockedTb4b4b4,
Te6edf3limitTff7b72=T79c0ff50Tb4b4b4,
Te6edf3offsetTff7b72=T79c0ff0Tb4b4b4,
Tb4b4b4)
Te6edf3durationsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msTb4b4b4)
Te6edf3stats Tff7b72= Te6edf3latency_reportTb4b4b4(Ta5d6ff"Ta5d6ffsearch+blockedTa5d6ff"Tb4b4b4, Te6edf3durationsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertLessTb4b4b4(Te6edf3statsTb4b4b4[Ta5d6ff"Ta5d6ffp95Ta5d6ff"Tb4b4b4]Tb4b4b4, T79c0ff200Tb4b4b4, Ta5d6ff"Ta5d6ffAnnounce search+blocked p95 > 200msTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8fftest_announce_count_latencyTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Count announces (used for pagination total)."""
Tffa657printTb4b4b4(Ta5d6ff"Tffea00\nTa5d6ff[Announce] Count:Ta5d6ff"Tb4b4b4)
Te6edf3durations Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3_ Tff7b72in Tffa657rangeTb4b4b4(T79c0ff30Tb4b4b4)Tb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3ms Tff7b72= Te6edf3timed_callTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffannounce_mgrTff7b72.Td2a8ffget_filtered_announces_countTb4b4b4,
Te6edf3aspectTff7b72=Ta5d6ff"Ta5d6fflxmf.deliveryTa5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3durationsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msTb4b4b4)
Te6edf3stats Tff7b72= Te6edf3latency_reportTb4b4b4(Ta5d6ff"Ta5d6ffcountTa5d6ff"Tb4b4b4, Te6edf3durationsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertLessTb4b4b4(Te6edf3statsTb4b4b4[Ta5d6ff"Ta5d6ffp95Ta5d6ff"Tb4b4b4]Tb4b4b4, T79c0ff100Tb4b4b4, Ta5d6ff"Ta5d6ffAnnounce count p95 > 100msTa5d6ff"Tb4b4b4)
T8b949e# ===================================================================
T8b949e# FAVOURITES
T8b949e# ===================================================================
Tff7b72def Td2a8fftest_favourites_load_latencyTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Load all favourites — typically displayed in sidebar."""
Tffa657printTb4b4b4(Ta5d6ff"Tffea00\nTa5d6ff[Favourites] Load all:Ta5d6ff"Tb4b4b4)
Te6edf3durations Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3_ Tff7b72in Tffa657rangeTb4b4b4(T79c0ff50Tb4b4b4)Tb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3ms Tff7b72= Te6edf3timed_callTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdbTff7b72.Td2a8ffannouncesTff7b72.Td2a8ffget_favouritesTb4b4b4, Ta5d6ff"Ta5d6fflxmf.deliveryTa5d6ff"Tb4b4b4)
Te6edf3durationsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msTb4b4b4)
Te6edf3stats Tff7b72= Te6edf3latency_reportTb4b4b4(Ta5d6ff"Ta5d6ffload_favsTa5d6ff"Tb4b4b4, Te6edf3durationsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertLessTb4b4b4(Te6edf3statsTb4b4b4[Ta5d6ff"Ta5d6ffp95Ta5d6ff"Tb4b4b4]Tb4b4b4, T79c0ff20Tb4b4b4, Ta5d6ff"Ta5d6ffFavourites load p95 > 20msTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8fftest_favourite_upsert_throughputTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Measure upsert throughput for favourites."""
Tffa657printTb4b4b4(Ta5d6ff"Tffea00\nTa5d6ff[Favourites] Upsert throughput:Ta5d6ff"Tb4b4b4)
Te6edf3durations Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3i Tff7b72in Tffa657rangeTb4b4b4(T79c0ff100Tb4b4b4)Tb4b4b4:
Te6edf3dest Tff7b72= Te6edf3secretsTff7b72.Td2a8fftoken_hexTb4b4b4(T79c0ff16Tb4b4b4)
Te6edf3_Tb4b4b4, Te6edf3ms Tff7b72= Te6edf3timed_callTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffdbTff7b72.Td2a8ffannouncesTff7b72.Td2a8ffupsert_favouriteTb4b4b4,
Te6edf3destTb4b4b4, Ta5d6fffTa5d6ff"Ta5d6ffBench Fav Tffd700{Te6edf3iTffd700}Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6fflxmf.deliveryTa5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3durationsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msTb4b4b4)
Te6edf3stats Tff7b72= Te6edf3latency_reportTb4b4b4(Ta5d6ff"Ta5d6ffupsert_favTa5d6ff"Tb4b4b4, Te6edf3durationsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertGreaterTb4b4b4(Te6edf3statsTb4b4b4[Ta5d6ff"Ta5d6ffopsTa5d6ff"Tb4b4b4]Tb4b4b4, T79c0ff500Tb4b4b4, Ta5d6ff"Ta5d6ffFavourite upsert < 500 ops/sTa5d6ff"Tb4b4b4)
T8b949e# ===================================================================
T8b949e# CONVERSATIONS — load, search
T8b949e# ===================================================================
Tff7b72def Td2a8fftest_conversations_load_latencyTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Load conversation list — the main messages sidebar query."""
Tffa657printTb4b4b4(Ta5d6ff"Tffea00\nTa5d6ff[Conversations] Load list (with JOINs):Ta5d6ff"Tb4b4b4)
Te6edf3durations Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3_ Tff7b72in Tffa657rangeTb4b4b4(T79c0ff20Tb4b4b4)Tb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3ms Tff7b72= Te6edf3timed_callTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffhandlerTff7b72.Td2a8ffget_conversationsTb4b4b4,
Ta5d6ff"Ta5d6fflocal_hashTa5d6ff"Tb4b4b4,
Te6edf3limitTff7b72=T79c0ff50Tb4b4b4,
Te6edf3offsetTff7b72=T79c0ff0Tb4b4b4,
Tb4b4b4)
Te6edf3durationsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msTb4b4b4)
Te6edf3stats Tff7b72= Te6edf3latency_reportTb4b4b4(Ta5d6ff"Ta5d6ffload_conversationsTa5d6ff"Tb4b4b4, Te6edf3durationsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertLessTb4b4b4(Te6edf3statsTb4b4b4[Ta5d6ff"Ta5d6ffp95Ta5d6ff"Tb4b4b4]Tb4b4b4, T79c0ff200Tb4b4b4, Ta5d6ff"Ta5d6ffConversation list p95 > 200msTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8fftest_conversations_search_latencyTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Search conversations — LIKE across titles, content, peer hashes."""
Tffa657printTb4b4b4(Ta5d6ff"Tffea00\nTa5d6ff[Conversations] Search:Ta5d6ff"Tb4b4b4)
Te6edf3terms Tff7b72= Tb4b4b4[Ta5d6ff"Ta5d6ffMessage title 5Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffContent bodyTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffabcTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffzzz_nopeTa5d6ff"Tb4b4b4, Tff7b72selfTff7b72.Td2a8ffheavy_peerTb4b4b4[Tb4b4b4:T79c0ff8Tb4b4b4]Tb4b4b4]
Te6edf3durations Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3term Tff7b72in Te6edf3termsTb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3ms Tff7b72= Te6edf3timed_callTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffhandlerTff7b72.Td2a8ffget_conversationsTb4b4b4,
Ta5d6ff"Ta5d6fflocal_hashTa5d6ff"Tb4b4b4,
Te6edf3searchTff7b72=Te6edf3termTb4b4b4,
Te6edf3limitTff7b72=T79c0ff50Tb4b4b4,
Tb4b4b4)
Te6edf3durationsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msTb4b4b4)
Te6edf3stats Tff7b72= Te6edf3latency_reportTb4b4b4(Ta5d6ff"Ta5d6ffsearch_conversationsTa5d6ff"Tb4b4b4, Te6edf3durationsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertLessTb4b4b4(Te6edf3statsTb4b4b4[Ta5d6ff"Ta5d6ffp95Ta5d6ff"Tb4b4b4]Tb4b4b4, T79c0ff500Tb4b4b4, Ta5d6ff"Ta5d6ffConversation search p95 > 500msTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8fftest_conversations_load_paginatedTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Paginate through conversation list at various offsets."""
Tffa657printTb4b4b4(Ta5d6ff"Tffea00\nTa5d6ff[Conversations] Paginated load:Ta5d6ff"Tb4b4b4)
Te6edf3durations Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3offset Tff7b72in Tb4b4b4[T79c0ff0Tb4b4b4, T79c0ff20Tb4b4b4, T79c0ff50Tb4b4b4, T79c0ff100Tb4b4b4, T79c0ff150Tb4b4b4]Tb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3ms Tff7b72= Te6edf3timed_callTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffhandlerTff7b72.Td2a8ffget_conversationsTb4b4b4,
Ta5d6ff"Ta5d6fflocal_hashTa5d6ff"Tb4b4b4,
Te6edf3limitTff7b72=T79c0ff20Tb4b4b4,
Te6edf3offsetTff7b72=Te6edf3offsetTb4b4b4,
Tb4b4b4)
Te6edf3durationsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msTb4b4b4)
Te6edf3stats Tff7b72= Te6edf3latency_reportTb4b4b4(Ta5d6ff"Ta5d6ffpaginated_conversationsTa5d6ff"Tb4b4b4, Te6edf3durationsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertLessTb4b4b4(Te6edf3statsTb4b4b4[Ta5d6ff"Ta5d6ffp95Ta5d6ff"Tb4b4b4]Tb4b4b4, T79c0ff300Tb4b4b4, Ta5d6ff"Ta5d6ffPaginated conversations p95 > 300msTa5d6ff"Tb4b4b4)
T8b949e# ===================================================================
T8b949e# MESSAGES — load, search, upsert (drafts)
T8b949e# ===================================================================
Tff7b72def Td2a8fftest_message_load_latencyTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Load messages for a single conversation (heavy peer with 2000 msgs)."""
Tffa657printTb4b4b4(Ta5d6ff"Tffea00\nTa5d6ff[Messages] Load conversation messages:Ta5d6ff"Tb4b4b4)
Te6edf3durations Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3offsets Tff7b72= Tb4b4b4[T79c0ff0Tb4b4b4, T79c0ff100Tb4b4b4, T79c0ff500Tb4b4b4, T79c0ff1000Tb4b4b4, T79c0ff1900Tb4b4b4]
Tff7b72for Te6edf3offset Tff7b72in Te6edf3offsetsTb4b4b4:
Te6edf3resultTb4b4b4, Te6edf3ms Tff7b72= Te6edf3timed_callTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffhandlerTff7b72.Td2a8ffget_conversation_messagesTb4b4b4,
Ta5d6ff"Ta5d6fflocal_hashTa5d6ff"Tb4b4b4,
Tff7b72selfTff7b72.Td2a8ffheavy_peerTb4b4b4,
Te6edf3limitTff7b72=T79c0ff50Tb4b4b4,
Te6edf3offsetTff7b72=Te6edf3offsetTb4b4b4,
Tb4b4b4)
Te6edf3durationsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertEqualTb4b4b4(Tffa657lenTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4, T79c0ff50Tb4b4b4)
Te6edf3stats Tff7b72= Te6edf3latency_reportTb4b4b4(Ta5d6ff"Ta5d6ffload_messagesTa5d6ff"Tb4b4b4, Te6edf3durationsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertLessTb4b4b4(Te6edf3statsTb4b4b4[Ta5d6ff"Ta5d6ffp99Ta5d6ff"Tb4b4b4]Tb4b4b4, T79c0ff50Tb4b4b4, Ta5d6ff"Ta5d6ffMessage load p99 > 50msTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8fftest_message_search_latencyTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Search messages across all conversations — the global search."""
Tffa657printTb4b4b4(Ta5d6ff"Tffea00\nTa5d6ff[Messages] Global search:Ta5d6ff"Tb4b4b4)
Te6edf3terms Tff7b72= Tb4b4b4[
Ta5d6ff"Ta5d6ffMessage title 100Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffContent body 5000Ta5d6ff"Tb4b4b4,
Te6edf3secretsTff7b72.Td2a8fftoken_hexTb4b4b4(T79c0ff4Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffnonexistent_xyz_123Ta5d6ff"Tb4b4b4,
Tb4b4b4]
Te6edf3durations Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3term Tff7b72in Te6edf3termsTb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3ms Tff7b72= Te6edf3timed_callTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffhandlerTff7b72.Td2a8ffsearch_messagesTb4b4b4,
Ta5d6ff"Ta5d6fflocal_hashTa5d6ff"Tb4b4b4,
Te6edf3termTb4b4b4,
Tb4b4b4)
Te6edf3durationsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msTb4b4b4)
Te6edf3stats Tff7b72= Te6edf3latency_reportTb4b4b4(Ta5d6ff"Ta5d6ffsearch_messagesTa5d6ff"Tb4b4b4, Te6edf3durationsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertLessTb4b4b4(Te6edf3statsTb4b4b4[Ta5d6ff"Ta5d6ffp95Ta5d6ff"Tb4b4b4]Tb4b4b4, T79c0ff300Tb4b4b4, Ta5d6ff"Ta5d6ffMessage search p95 > 300msTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8fftest_message_upsert_throughputTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Measure message upsert throughput — simulates saving drafts rapidly."""
Tffa657printTb4b4b4(Ta5d6ff"Tffea00\nTa5d6ff[Messages] Upsert throughput (draft saves):Ta5d6ff"Tb4b4b4)
Te6edf3durations Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3peer Tff7b72= Te6edf3secretsTff7b72.Td2a8fftoken_hexTb4b4b4(T79c0ff16Tb4b4b4)
Tff7b72for Te6edf3i Tff7b72in Tffa657rangeTb4b4b4(T79c0ff200Tb4b4b4)Tb4b4b4:
Te6edf3msg Tff7b72= Te6edf3make_messageTb4b4b4(Te6edf3peerTb4b4b4, Te6edf3i Tff7b72+ T79c0ff100000Tb4b4b4)
Te6edf3_Tb4b4b4, Te6edf3ms Tff7b72= Te6edf3timed_callTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdbTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffupsert_lxmf_messageTb4b4b4, Te6edf3msgTb4b4b4)
Te6edf3durationsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msTb4b4b4)
Te6edf3stats Tff7b72= Te6edf3latency_reportTb4b4b4(Ta5d6ff"Ta5d6ffupsert_messageTa5d6ff"Tb4b4b4, Te6edf3durationsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertGreaterTb4b4b4(Te6edf3statsTb4b4b4[Ta5d6ff"Ta5d6ffopsTa5d6ff"Tb4b4b4]Tb4b4b4, T79c0ff300Tb4b4b4, Ta5d6ff"Ta5d6ffMessage upsert < 300 ops/sTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertLessTb4b4b4(Te6edf3statsTb4b4b4[Ta5d6ff"Ta5d6ffp95Ta5d6ff"Tb4b4b4]Tb4b4b4, T79c0ff10Tb4b4b4, Ta5d6ff"Ta5d6ffMessage upsert p95 > 10msTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8fftest_message_upsert_update_throughputTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Measure message UPDATE throughput — re-saving existing messages (state changes)."""
Tffa657printTb4b4b4(Ta5d6ff"Tffea00\nTa5d6ff[Messages] Update existing messages:Ta5d6ff"Tb4b4b4)
Te6edf3peer Tff7b72= Te6edf3secretsTff7b72.Td2a8fftoken_hexTb4b4b4(T79c0ff16Tb4b4b4)
Te6edf3msgs Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3i Tff7b72in Tffa657rangeTb4b4b4(T79c0ff100Tb4b4b4)Tb4b4b4:
Te6edf3msg Tff7b72= Te6edf3make_messageTb4b4b4(Te6edf3peerTb4b4b4, Te6edf3i Tff7b72+ T79c0ff200000Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffdbTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffupsert_lxmf_messageTb4b4b4(Te6edf3msgTb4b4b4)
Te6edf3msgsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msgTb4b4b4)
Te6edf3durations Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3msg Tff7b72in Te6edf3msgsTb4b4b4:
Te6edf3msgTb4b4b4[Ta5d6ff"Ta5d6ffstateTa5d6ff"Tb4b4b4] Tff7b72= Ta5d6ff"Ta5d6fffailedTa5d6ff"
Te6edf3msgTb4b4b4[Ta5d6ff"Ta5d6ffcontentTa5d6ff"Tb4b4b4] Tff7b72= Ta5d6ff"Ta5d6ffUpdated content Ta5d6ff" Tff7b72+ Te6edf3secretsTff7b72.Td2a8fftoken_hexTb4b4b4(T79c0ff16Tb4b4b4)
Te6edf3_Tb4b4b4, Te6edf3ms Tff7b72= Te6edf3timed_callTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdbTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffupsert_lxmf_messageTb4b4b4, Te6edf3msgTb4b4b4)
Te6edf3durationsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msTb4b4b4)
Te6edf3stats Tff7b72= Te6edf3latency_reportTb4b4b4(Ta5d6ff"Ta5d6ffupdate_messageTa5d6ff"Tb4b4b4, Te6edf3durationsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertGreaterTb4b4b4(Te6edf3statsTb4b4b4[Ta5d6ff"Ta5d6ffopsTa5d6ff"Tb4b4b4]Tb4b4b4, T79c0ff300Tb4b4b4, Ta5d6ff"Ta5d6ffMessage update < 300 ops/sTa5d6ff"Tb4b4b4)
T8b949e# ===================================================================
T8b949e# CONCURRENT WRITERS — contention stress
T8b949e# ===================================================================
Tff7b72def Td2a8fftest_concurrent_message_writersTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Multiple threads inserting messages simultaneously."""
Tffa657printTb4b4b4(Ta5d6ff"Tffea00\nTa5d6ff[Concurrency] Message writers:Ta5d6ff"Tb4b4b4)
Te6edf3num_threads Tff7b72= T79c0ff8
Te6edf3msgs_per_thread Tff7b72= T79c0ff100
Te6edf3errors Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3all_durations Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3lock Tff7b72= Te6edf3threadingTff7b72.Td2a8ffLockTb4b4b4(Tb4b4b4)
Tff7b72def Td2a8ffwriterTb4b4b4(Te6edf3thread_idTb4b4b4)Tb4b4b4:
Te6edf3thread_durations Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3peer Tff7b72= Te6edf3secretsTff7b72.Td2a8fftoken_hexTb4b4b4(T79c0ff16Tb4b4b4)
Tff7b72for Te6edf3i Tff7b72in Tffa657rangeTb4b4b4(Te6edf3msgs_per_threadTb4b4b4)Tb4b4b4:
Te6edf3msg Tff7b72= Te6edf3make_messageTb4b4b4(Te6edf3peerTb4b4b4, Te6edf3thread_id Tff7b72* T79c0ff10000 Tff7b72+ Te6edf3iTb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3ms Tff7b72= Te6edf3timed_callTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdbTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffupsert_lxmf_messageTb4b4b4, Te6edf3msgTb4b4b4)
Te6edf3thread_durationsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3errorsTff7b72.Td2a8ffappendTb4b4b4(Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4)
Tff7b72with Te6edf3lockTb4b4b4:
Te6edf3all_durationsTff7b72.Td2a8ffextendTb4b4b4(Te6edf3thread_durationsTb4b4b4)
Te6edf3threads Tff7b72= Tb4b4b4[Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Te6edf3writerTb4b4b4, Te6edf3argsTff7b72=Tb4b4b4(Te6edf3tTb4b4b4,Tb4b4b4)Tb4b4b4) Tff7b72for Te6edf3t Tff7b72in Tffa657rangeTb4b4b4(Te6edf3num_threadsTb4b4b4)Tb4b4b4]
Te6edf3t0 Tff7b72= Te6edf3timeTff7b72.Td2a8ffperf_counterTb4b4b4(Tb4b4b4)
Tff7b72for Te6edf3t Tff7b72in Te6edf3threadsTb4b4b4:
Te6edf3tTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)
Tff7b72for Te6edf3t Tff7b72in Te6edf3threadsTb4b4b4:
Te6edf3tTff7b72.Td2a8ffjoinTb4b4b4(Tb4b4b4)
Te6edf3wall_ms Tff7b72= Tb4b4b4(Te6edf3timeTff7b72.Td2a8ffperf_counterTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3t0Tb4b4b4) Tff7b72* T79c0ff1000
Te6edf3total_ops Tff7b72= Te6edf3num_threads Tff7b72* Te6edf3msgs_per_thread
Te6edf3throughput Tff7b72= Te6edf3total_ops Tff7b72/ Tb4b4b4(Te6edf3wall_ms Tff7b72/ T79c0ff1000Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ff Wall time: Tffd700{Te6edf3wall_msTffd700:Ta5d6ff.0fTffd700}Ta5d6ffms for Tffd700{Te6edf3total_opsTffd700}Ta5d6ff inserts (Tffd700{Te6edf3throughputTffd700:Ta5d6ff.0fTffd700}Ta5d6ff ops/s)Ta5d6ff"Tb4b4b4)
Te6edf3stats Tff7b72= Te6edf3latency_reportTb4b4b4(Ta5d6ff"Ta5d6ffconcurrent_writeTa5d6ff"Tb4b4b4, Te6edf3all_durationsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertEqualTb4b4b4(Tffa657lenTb4b4b4(Te6edf3errorsTb4b4b4)Tb4b4b4, T79c0ff0Tb4b4b4, Ta5d6fffTa5d6ff"Ta5d6ffWriter errors: Tffd700{Te6edf3errorsTb4b4b4[Tb4b4b4:T79c0ff5Tb4b4b4]Tffd700}Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertGreaterTb4b4b4(Te6edf3throughputTb4b4b4, T79c0ff100Tb4b4b4, Ta5d6ff"Ta5d6ffConcurrent write throughput < 100 ops/sTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8fftest_concurrent_announce_writersTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Multiple threads upserting announces simultaneously."""
Tffa657printTb4b4b4(Ta5d6ff"Tffea00\nTa5d6ff[Concurrency] Announce writers:Ta5d6ff"Tb4b4b4)
Te6edf3num_threads Tff7b72= T79c0ff6
Te6edf3announces_per_thread Tff7b72= T79c0ff100
Te6edf3errors Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3all_durations Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3lock Tff7b72= Te6edf3threadingTff7b72.Td2a8ffLockTb4b4b4(Tb4b4b4)
Tff7b72def Td2a8ffwriterTb4b4b4(Te6edf3thread_idTb4b4b4)Tb4b4b4:
Te6edf3thread_durations Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3i Tff7b72in Tffa657rangeTb4b4b4(Te6edf3announces_per_threadTb4b4b4)Tb4b4b4:
Te6edf3data Tff7b72= Te6edf3make_announceTb4b4b4(Te6edf3thread_id Tff7b72* T79c0ff10000 Tff7b72+ Te6edf3iTb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3ms Tff7b72= Te6edf3timed_callTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdbTff7b72.Td2a8ffannouncesTff7b72.Td2a8ffupsert_announceTb4b4b4, Te6edf3dataTb4b4b4)
Te6edf3thread_durationsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3errorsTff7b72.Td2a8ffappendTb4b4b4(Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4)
Tff7b72with Te6edf3lockTb4b4b4:
Te6edf3all_durationsTff7b72.Td2a8ffextendTb4b4b4(Te6edf3thread_durationsTb4b4b4)
Te6edf3threads Tff7b72= Tb4b4b4[Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Te6edf3writerTb4b4b4, Te6edf3argsTff7b72=Tb4b4b4(Te6edf3tTb4b4b4,Tb4b4b4)Tb4b4b4) Tff7b72for Te6edf3t Tff7b72in Tffa657rangeTb4b4b4(Te6edf3num_threadsTb4b4b4)Tb4b4b4]
Te6edf3t0 Tff7b72= Te6edf3timeTff7b72.Td2a8ffperf_counterTb4b4b4(Tb4b4b4)
Tff7b72for Te6edf3t Tff7b72in Te6edf3threadsTb4b4b4:
Te6edf3tTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)
Tff7b72for Te6edf3t Tff7b72in Te6edf3threadsTb4b4b4:
Te6edf3tTff7b72.Td2a8ffjoinTb4b4b4(Tb4b4b4)
Te6edf3wall_ms Tff7b72= Tb4b4b4(Te6edf3timeTff7b72.Td2a8ffperf_counterTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3t0Tb4b4b4) Tff7b72* T79c0ff1000
Te6edf3total_ops Tff7b72= Te6edf3num_threads Tff7b72* Te6edf3announces_per_thread
Te6edf3throughput Tff7b72= Te6edf3total_ops Tff7b72/ Tb4b4b4(Te6edf3wall_ms Tff7b72/ T79c0ff1000Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ff Wall time: Tffd700{Te6edf3wall_msTffd700:Ta5d6ff.0fTffd700}Ta5d6ffms for Tffd700{Te6edf3total_opsTffd700}Ta5d6ff upserts (Tffd700{Te6edf3throughputTffd700:Ta5d6ff.0fTffd700}Ta5d6ff ops/s)Ta5d6ff"Tb4b4b4)
Te6edf3stats Tff7b72= Te6edf3latency_reportTb4b4b4(Ta5d6ff"Ta5d6ffconcurrent_announce_writeTa5d6ff"Tb4b4b4, Te6edf3all_durationsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertEqualTb4b4b4(Tffa657lenTb4b4b4(Te6edf3errorsTb4b4b4)Tb4b4b4, T79c0ff0Tb4b4b4, Ta5d6fffTa5d6ff"Ta5d6ffWriter errors: Tffd700{Te6edf3errorsTb4b4b4[Tb4b4b4:T79c0ff5Tb4b4b4]Tffd700}Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertGreaterTb4b4b4(Te6edf3throughputTb4b4b4, T79c0ff100Tb4b4b4, Ta5d6ff"Ta5d6ffConcurrent announce write < 100 ops/sTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8fftest_concurrent_read_write_contentionTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Writers inserting while readers query — simulates real app usage."""
Tffa657printTb4b4b4(Ta5d6ff"Tffea00\nTa5d6ff[Contention] Mixed read/write:Ta5d6ff"Tb4b4b4)
Te6edf3num_writers Tff7b72= T79c0ff4
Te6edf3num_readers Tff7b72= T79c0ff4
Te6edf3ops_per_thread Tff7b72= T79c0ff50
Te6edf3write_errors Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3read_errors Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3write_durations Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3read_durations Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3lock Tff7b72= Te6edf3threadingTff7b72.Td2a8ffLockTb4b4b4(Tb4b4b4)
Tff7b72def Td2a8ffwriterTb4b4b4(Te6edf3thread_idTb4b4b4)Tb4b4b4:
Te6edf3local_durs Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3peer Tff7b72= Te6edf3secretsTff7b72.Td2a8fftoken_hexTb4b4b4(T79c0ff16Tb4b4b4)
Tff7b72for Te6edf3i Tff7b72in Tffa657rangeTb4b4b4(Te6edf3ops_per_threadTb4b4b4)Tb4b4b4:
Te6edf3msg Tff7b72= Te6edf3make_messageTb4b4b4(Te6edf3peerTb4b4b4, Te6edf3thread_id Tff7b72* T79c0ff10000 Tff7b72+ Te6edf3iTb4b4b4)
Tff7b72tryTb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3ms Tff7b72= Te6edf3timed_callTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdbTff7b72.Td2a8ffmessagesTff7b72.Td2a8ffupsert_lxmf_messageTb4b4b4, Te6edf3msgTb4b4b4)
Te6edf3local_dursTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3write_errorsTff7b72.Td2a8ffappendTb4b4b4(Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4)
Tff7b72with Te6edf3lockTb4b4b4:
Te6edf3write_durationsTff7b72.Td2a8ffextendTb4b4b4(Te6edf3local_dursTb4b4b4)
Tff7b72def Td2a8ffreaderTb4b4b4(Te6edf3_thread_idTb4b4b4)Tb4b4b4:
Te6edf3local_durs Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3_ Tff7b72in Tffa657rangeTb4b4b4(Te6edf3ops_per_threadTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3_Tb4b4b4, Te6edf3ms Tff7b72= Te6edf3timed_callTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffhandlerTff7b72.Td2a8ffget_conversationsTb4b4b4,
Ta5d6ff"Ta5d6fflocal_hashTa5d6ff"Tb4b4b4,
Te6edf3limitTff7b72=T79c0ff20Tb4b4b4,
Tb4b4b4)
Te6edf3local_dursTff7b72.Td2a8ffappendTb4b4b4(Te6edf3msTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3read_errorsTff7b72.Td2a8ffappendTb4b4b4(Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4)
Tff7b72with Te6edf3lockTb4b4b4:
Te6edf3read_durationsTff7b72.Td2a8ffextendTb4b4b4(Te6edf3local_dursTb4b4b4)
Te6edf3writers Tff7b72= Tb4b4b4[Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Te6edf3writerTb4b4b4, Te6edf3argsTff7b72=Tb4b4b4(Te6edf3tTb4b4b4,Tb4b4b4)Tb4b4b4) Tff7b72for Te6edf3t Tff7b72in Tffa657rangeTb4b4b4(Te6edf3num_writersTb4b4b4)Tb4b4b4]
Te6edf3readers Tff7b72= Tb4b4b4[Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Te6edf3readerTb4b4b4, Te6edf3argsTff7b72=Tb4b4b4(Te6edf3tTb4b4b4,Tb4b4b4)Tb4b4b4) Tff7b72for Te6edf3t Tff7b72in Tffa657rangeTb4b4b4(Te6edf3num_readersTb4b4b4)Tb4b4b4]
Te6edf3t0 Tff7b72= Te6edf3timeTff7b72.Td2a8ffperf_counterTb4b4b4(Tb4b4b4)
Tff7b72for Te6edf3t Tff7b72in Te6edf3writers Tff7b72+ Te6edf3readersTb4b4b4:
Te6edf3tTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)
Tff7b72for Te6edf3t Tff7b72in Te6edf3writers Tff7b72+ Te6edf3readersTb4b4b4:
Te6edf3tTff7b72.Td2a8ffjoinTb4b4b4(Tb4b4b4)
Te6edf3wall_ms Tff7b72= Tb4b4b4(Te6edf3timeTff7b72.Td2a8ffperf_counterTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3t0Tb4b4b4) Tff7b72* T79c0ff1000
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ff Wall time: Tffd700{Te6edf3wall_msTffd700:Ta5d6ff.0fTffd700}Ta5d6ffmsTa5d6ff"Tb4b4b4)
Te6edf3latency_reportTb4b4b4(Ta5d6ff"Ta5d6ffcontention_writesTa5d6ff"Tb4b4b4, Te6edf3write_durationsTb4b4b4)
Te6edf3latency_reportTb4b4b4(Ta5d6ff"Ta5d6ffcontention_readsTa5d6ff"Tb4b4b4, Te6edf3read_durationsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertEqualTb4b4b4(Tffa657lenTb4b4b4(Te6edf3write_errorsTb4b4b4)Tb4b4b4, T79c0ff0Tb4b4b4, Ta5d6fffTa5d6ff"Ta5d6ffWrite errors: Tffd700{Te6edf3write_errorsTb4b4b4[Tb4b4b4:T79c0ff5Tb4b4b4]Tffd700}Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertEqualTb4b4b4(Tffa657lenTb4b4b4(Te6edf3read_errorsTb4b4b4)Tb4b4b4, T79c0ff0Tb4b4b4, Ta5d6fffTa5d6ff"Ta5d6ffRead errors: Tffd700{Te6edf3read_errorsTb4b4b4[Tb4b4b4:T79c0ff5Tb4b4b4]Tffd700}Ta5d6ff"Tb4b4b4)
T8b949e# ===================================================================
T8b949e# LIKE SEARCH SCALING — how search degrades with data size
T8b949e# ===================================================================
Tff7b72def Td2a8fftest_like_search_scalingTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Measure how LIKE search scales across different table sizes.
This catches missing FTS indexes or query plan regressions."""
Tffa657printTb4b4b4(Ta5d6ff"Tffea00\nTa5d6ff[Scaling] LIKE search across data sizes:Ta5d6ff"Tb4b4b4)
T8b949e# Message search on the existing 10k dataset
Te6edf3_Tb4b4b4, Te6edf3ms_msg Tff7b72= Te6edf3timed_callTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffhandlerTff7b72.Td2a8ffsearch_messagesTb4b4b4,
Ta5d6ff"Ta5d6fflocal_hashTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffContent bodyTa5d6ff"Tb4b4b4,
Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ff Message LIKE search (Tffd700{Tff7b72selfTff7b72.Td2a8ffNUM_MESSAGESTffd700}Ta5d6ff rows): Tffd700{Te6edf3ms_msgTffd700:Ta5d6ff.2fTffd700}Ta5d6ffmsTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertLessTb4b4b4(Te6edf3ms_msgTb4b4b4, T79c0ff500Tb4b4b4, Ta5d6ff"Ta5d6ffMessage LIKE search > 500ms on 10k rowsTa5d6ff"Tb4b4b4)
T8b949e# Announce search on the existing 5k dataset
Te6edf3_Tb4b4b4, Te6edf3ms_ann Tff7b72= Te6edf3timed_callTb4b4b4(
Tff7b72selfTff7b72.Td2a8ffannounce_mgrTff7b72.Td2a8ffget_filtered_announcesTb4b4b4,
Te6edf3aspectTff7b72=Ta5d6ff"Ta5d6fflxmf.deliveryTa5d6ff"Tb4b4b4,
Te6edf3queryTff7b72=Ta5d6ff"Ta5d6ffabcTa5d6ff"Tb4b4b4,
Te6edf3limitTff7b72=T79c0ff50Tb4b4b4,
Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ff Announce LIKE search (Tffd700{Tff7b72selfTff7b72.Td2a8ffNUM_ANNOUNCESTffd700}Ta5d6ff rows): Tffd700{Te6edf3ms_annTffd700:Ta5d6ff.2fTffd700}Ta5d6ffmsTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertLessTb4b4b4(Te6edf3ms_annTb4b4b4, T79c0ff200Tb4b4b4, Ta5d6ff"Ta5d6ffAnnounce LIKE search > 200ms on 5k rowsTa5d6ff"Tb4b4b4)
T8b949e# Contacts search
Te6edf3_Tb4b4b4, Te6edf3ms_con Tff7b72= Te6edf3timed_callTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdbTff7b72.Td2a8ffcontactsTff7b72.Td2a8ffget_contactsTb4b4b4, Te6edf3searchTff7b72=Ta5d6ff"Ta5d6ffContactTa5d6ff"Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ff Contacts LIKE search (Tffd700{Tff7b72selfTff7b72.Td2a8ffNUM_CONTACTSTffd700}Ta5d6ff rows): Tffd700{Te6edf3ms_conTffd700:Ta5d6ff.2fTffd700}Ta5d6ffmsTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffassertLessTb4b4b4(Te6edf3ms_conTb4b4b4, T79c0ff50Tb4b4b4, Ta5d6ff"Ta5d6ffContacts LIKE search > 50msTa5d6ff"Tb4b4b4)
Tff7b72if Tff7b72__name__ Tff7b72== Ta5d6ff"Ta5d6ff__main__Ta5d6ff"Tb4b4b4:
Te6edf3unittestTff7b72.Td2a8ffmainTb4b4b4(Tb4b4b4)
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────